package com.example.demo.controller;

import com.example.demo.dto.ResponseDTO;
import com.example.demo.exception.LibraryException;
import com.example.demo.model.Book;
import com.example.demo.model.User;
import com.example.demo.service.LibraryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
//import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.constraints.Min;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/books")
@Validated  // 启用参数校验
@Api(tags = "图书借阅管理接口")
public class BookController {

    @Autowired
    private LibraryService libraryService;

    @PostMapping("/borrow")
    @ApiOperation(value = "借阅书籍", notes = "用户通过用户ID和书籍ID借阅指定书籍")
    //@PreAuthorize("hasRole('USER')") // 仅允许普通用户
    public ResponseEntity<ResponseDTO<String>> borrowBook(
            @ApiParam(value = "用户ID", required = true, example = "1")
            @RequestParam @Min(value = 1, message = "用户ID必须大于0") Long userId,

            @ApiParam(value = "书籍ID", required = true, example = "1")
            @RequestParam @Min(value = 1, message = "书籍ID必须大于0") Long bookId
    ) {
        try {
            User user = libraryService.findUserById(userId);
            Book book = libraryService.findBookById(bookId);
            libraryService.borrowBook(user, book);
            return ResponseEntity.ok(ResponseDTO.success("借书成功"));
        } catch (LibraryException e) {
            return ResponseEntity.badRequest().body(ResponseDTO.error(400, e.getMessage()));
        }

    }

    @PostMapping("/return")
    @ApiOperation(value = "归还书籍", notes = "用户归还书籍并计算逾期费用")
    //@PreAuthorize("hasRole('USER')") // 仅允许普通用户
    public ResponseEntity<ResponseDTO<Double>> returnBook(
            @ApiParam(value = "用户ID", required = true, example = "1")
            @RequestParam @Min(value = 1, message = "用户ID必须大于0") Long userId,

            @ApiParam(value = "书籍ID", required = true, example = "1")
            @RequestParam @Min(value = 1, message = "书籍ID必须大于0") Long bookId,

            @ApiParam(value = "逾期天数", required = true, example = "0")
            @RequestParam @Min(value = 0, message = "逾期天数不能为负数") int overdueDays
    ) {
        try {
            User user = libraryService.findUserById(userId);
            Book book = libraryService.findBookById(bookId);
            double fine = libraryService.returnBook(user, book, overdueDays);
            return ResponseEntity.ok(ResponseDTO.success(fine));
        } catch (LibraryException e) {
            return ResponseEntity.badRequest().body(ResponseDTO.error(400, e.getMessage()));
        }
    }


        // 其他方法...

        /**
         * 通过用户ID和书籍ID借阅书籍.
         *
         * @param userId 用户ID
         * @param bookId 书籍ID
         * @return 响应对象
         */
        @PostMapping("/borrowById")
        @ApiOperation(value = "通过ID借阅书籍")
        public ResponseEntity<ResponseDTO<String>> borrowBookById(
                @RequestParam Long userId,
                @RequestParam Long bookId) {
            try {
                libraryService.borrowBookById(userId, bookId);
                return ResponseEntity.ok(ResponseDTO.success("借书成功"));
            } catch (LibraryException e) {
                return ResponseEntity.badRequest().body(ResponseDTO.error(e.getStatusCode(), e.getMessage()));
            }
        }


    // 全局异常处理（可单独提取到 @ControllerAdvice）
    @ExceptionHandler(ConstraintViolationException.class)
    public ResponseEntity<ResponseDTO<String>> handleValidationException(ConstraintViolationException ex) {
        String errorMsg = ex.getConstraintViolations().stream()
                .map(ConstraintViolation::getMessage)
                .collect(Collectors.joining(", "));
        return ResponseEntity.badRequest().body(ResponseDTO.error(400, "参数校验失败: " + errorMsg));
    }
}